package com.zhuangjie.openfeign.config;

import feign.Request;
import feign.RetryableException;
import feign.Retryer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 决定OpenFeign什么情况重试，重试的次数等等
 *
 * @author zhuangjie
 * @date 2023/11/08
 */
class GetRequestRetryer implements Retryer {

    private final int maxAttempts;
    private final long period;
    private int attempt;

    public GetRequestRetryer(int maxAttempts, long period) {
        this.maxAttempts = maxAttempts;
        this.period = period;
        this.attempt = 1;
    }

    @Override
    public void continueOrPropagate(RetryableException e) {
        // 如果是GET请求且没有超过指定重试次数则进行重试
        if (e.request().httpMethod() == Request.HttpMethod.GET && attempt++ <= maxAttempts) {
            try {
                Thread.sleep(period);
            } catch (InterruptedException ignored) {
                Thread.currentThread().interrupt();
            }
        } else {
            throw e;
        }
    }

    @Override
    public Retryer clone() {
        return new GetRequestRetryer(maxAttempts, period);
    }
}

@Configuration
public class OpenFeignGetRequestRetryConfiguration {
    /**
     * 配置OpenFeign重试器
     *
     * @return {@link Retryer}
     */
    @Bean
    public Retryer retryer(){
        /**
         * private final int maxAttempts; //最大重试次数，初始调用算一次，默认实现值是 5
         * private final long period;     //初始重试间隔 ，默认实现值是 100 ms
         */
        return new GetRequestRetryer(3,200);
    }
}
